package com.fcat.base.smartapi.util;


import com.fcat.base.smartapi.JFJLibrary;
import com.sun.jna.Platform;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.util.logging.Level;
import java.util.logging.Logger;

public class TokenUtils {
    static {
        String suffix = System.getProperty("os.name").toLowerCase().contains("linux") ? ".so" : ".dll";
        String arch = "x" + System.getProperty("sun.arch.data.model");

        try {
            String suffixName = "";
            if (suffix.equals(".dll")) {
                suffixName = "JFJEncryption";
            } else if (suffix.equals(".so")) {
                suffixName = "libJFJEncryption";
            }

            String fileName = suffixName + suffix;
            String resourceFile = "com/jfj/ami/spi/" + arch + "/" + fileName;
            if (CopyFileToJavaLibrary(resourceFile, suffix, fileName)) {
                System.loadLibrary(Platform.isWindows() ? "JFJEncryption" : "JFJEncryption");
            }
        } catch (Exception var5) {
            Logger.getLogger(TokenUtils.class.getName()).log(Level.SEVERE, (String)null, var5);
        }

    }

    public TokenUtils() {
    }

    public static String IntToBin(int amount, int len) {
        String result = "";
        result = String.format("%32s", Integer.toBinaryString(amount));
        result = result.replace(" ", "0");
        result = substring(result, result.length() - len, len);
        return result;
    }

    public static String LongToBin(long amount, int len) {
        String result = "";
        result = String.format("%64s", Long.toBinaryString(amount));
        result = result.replace(" ", "0");
        result = substring(result, result.length() - len, len);
        return result;
    }

    public static String HexToBin(String dataValue, int len) {
        String result = "";
        String binStr = "";
        BigInteger dec = new BigInteger(dataValue, 16);

        for(binStr = dec.toString(2); binStr.length() < len; binStr = "0" + binStr) {
        }

        result = substring(binStr, binStr.length() - len, len);
        return result;
    }

    public static String IntToHex(int amount, int len) {
        String result = "";
        String hexStr = "";

        for(hexStr = Integer.toHexString(amount); hexStr.length() < len; hexStr = "0" + hexStr) {
        }

        result = substring(hexStr, hexStr.length() - len, len);
        return result;
    }

    public static String IntToBCD(int amount, int len) {
        String result = "";
        String bcdStr = "";

        for(bcdStr = Integer.toString(amount); bcdStr.length() < len; bcdStr = "0" + bcdStr) {
        }

        result = substring(bcdStr, bcdStr.length() - len, len);
        return result;
    }

    public static String BigIntToBin(String dataValue, int len) {
        String result = "";
        String binStr = "";
        BigInteger bi = new BigInteger(dataValue);

        for(binStr = bi.toString(2); binStr.length() < len; binStr = "0" + binStr) {
        }

        result = substring(binStr, binStr.length() - len, len);
        return result;
    }

    public static String BinToDec(String dataValue) {
        String result = "";
        BigInteger dec = new BigInteger(dataValue, 2);
        result = dec.toString();
        return result;
    }

    public static String BinToHex(String dataValue, int len) {
        String result = "";
        String hexStr = "";
        BigInteger bi = new BigInteger(dataValue, 2);
        hexStr = bi.toString(16);

        for(hexStr = hexStr.toUpperCase(); hexStr.length() < len; hexStr = "0" + hexStr) {
        }

        result = substring(hexStr, hexStr.length() - len, len);
        return result;
    }

    public static int HexToInt(String dataValue) {
        return Integer.valueOf(dataValue, 16);
    }

    public static String ReverseData(String dataValue, int len) {
        String result = "";

        String dataByte;
        for(dataByte = ""; dataValue.length() < len; dataValue = "0" + dataValue) {
        }

        dataValue = substring(dataValue, dataValue.length() - len, len);
        int bytes = dataValue.length() / 2;

        for(int i = 0; i <= bytes - 1; ++i) {
            dataByte = substring(dataValue, i * 2, 2);
            result = dataByte + result;
        }

        return result;
    }

    public static String FillData(String dataValue, String fillValue, int len) {
        while(dataValue.length() < len) {
            dataValue = fillValue + dataValue;
        }

        dataValue = substring(dataValue, dataValue.length() - len, len);
        return dataValue;
    }

    public static String getDispenserPAN(String meterNo) {
        String result = "";
        String meterPAN = "";
        meterPAN = "600727" + meterNo;
        meterPAN = meterPAN + Luhn(meterPAN);
        result = meterPAN + " ";
        return result;
    }

    public static String Luhn(String dataValue) {
        int sum = 0;
        if (dataValue.length() <= 0) {
            return "";
        } else {
            for(int i = dataValue.length() - 1; i >= 0; --i) {
                sum += Integer.valueOf(substring(dataValue, i, i + 1)) * 2 >= 10 ? 1 + Integer.valueOf(substring(dataValue, i, i + 1)) * 2 % 10 : Integer.valueOf(substring(dataValue, i, i + 1)) * 2;
                --i;
                if (i >= 0) {
                    sum += Integer.valueOf(substring(dataValue, i, i + 1));
                }
            }

            if (sum % 10 == 0) {
                return "0";
            } else {
                return String.valueOf(10 - sum % 10);
            }
        }
    }

    public static String CheckSum(String dataValue) {
        String result = "";
        String hexByte = "";

        int sum;
        for(sum = 0; dataValue.length() % 8 != 0; dataValue = "0" + dataValue) {
        }

        int bytes = dataValue.length() / 8;

        for(int i = 0; i <= bytes - 1; ++i) {
            hexByte = substring(dataValue, i * 8, 8);
            sum += Integer.parseInt(hexByte, 2);
        }

        sum %= 256;
        result = IntToBin(sum, 8);
        return result;
    }

    public static String getRtnTokenCheckSum(String dataValue, int offSet) {
        String result = "";
        String hexByte = "";

        int sum;
        for(sum = 0; dataValue.length() % 8 != 0; dataValue = "0" + dataValue) {
        }

        int bytes = dataValue.length() / 8;

        for(int i = 0; i <= bytes - 1; ++i) {
            hexByte = substring(dataValue, i * 8, 8);
            sum += Integer.parseInt(hexByte, 2);
        }

        sum += offSet;
        sum %= 256;
        result = IntToBin(sum, 8);
        return result;
    }

    public static String getCheckSum(String dataValue) {
        String hexStr = "";
        String hexByte = "";

        long sum;
        for(sum = 0L; dataValue.length() % 2 != 0; dataValue = "0" + dataValue) {
        }

        int bytes = dataValue.length() / 2;

        for(int i = 0; i <= bytes - 1; ++i) {
            hexByte = substring(dataValue, i * 2, 2);
            sum += (long)Integer.parseInt(hexByte, 16);
        }

        sum %= 65536L;

        for(hexStr = Long.toHexString(sum); hexStr.length() < 4; hexStr = "0" + hexStr) {
        }

        hexStr = hexStr.substring(hexStr.length() - 4, hexStr.length());
        return hexStr;
    }

    //TODO 固定的一串
    public static String getDecoderKey(String meterNo, String tariffIndex, String sgcNo, String vendingKey, String keyType, String keyVersionNo) {
        String TI = "";
        String KRN = "";
        String controlBlock = "";
        String PANBlock = "";
        String vendingKeyBlock = "";
        keyType = "00" + keyType;
        keyType = substring(keyType, keyType.length() - 2, 2);
        sgcNo = "000000" + sgcNo;
        sgcNo = substring(sgcNo, sgcNo.length() - 6, 6);
        TI = tariffIndex.toString();
        TI = "00" + TI;
        TI = substring(TI, TI.length() - 2, 2);
        KRN = keyVersionNo.toString();
        KRN = "0" + KRN;
        KRN = substring(KRN, KRN.length() - 1, 1);

        for(controlBlock = keyType + sgcNo + TI + KRN + "FFFFF"; meterNo.length() < 16; meterNo = "0" + meterNo) {
        }

        meterNo = meterNo.substring(meterNo.length() - 16, meterNo.length());

        System.err.println("controlBlock: " + controlBlock + "    meterNo:" + meterNo + "    vendingKey:" + vendingKey);
        String decodeKey = FEncryptionAlgorithm02(controlBlock, meterNo, vendingKey);
        return decodeKey;
    }

    public static String FEncryptionAlgorithm02(String controlBlock, String PANBlock, String vendingKeyBlock) {
        System.err.println("FEncryptionAlgorithm02:::  controlBlock: " + controlBlock + "    PANBlock:" + PANBlock + "    vendingKeyBlock:" + vendingKeyBlock);
        String result = "";
        byte[] Output = new byte[512];
        byte[] controlBlock_Input = new byte[512];

        for(int i = 0; i < controlBlock.length() / 2; ++i) {
            controlBlock_Input[i] = (byte)Integer.parseInt(controlBlock.substring(2 * i, 2 * i + 2), 16);
        }

        byte[] PANBlock_Input = new byte[512];

        for(int i = 0; i < PANBlock.length() / 2; ++i) {
            PANBlock_Input[i] = (byte)Integer.parseInt(PANBlock.substring(2 * i, 2 * i + 2), 16);
        }

        byte[] vendingKeyBlock_Input = new byte[512];

        for(int i = 0; i < vendingKeyBlock.length() / 2; ++i) {
            vendingKeyBlock_Input[i] = (byte)Integer.parseInt(vendingKeyBlock.substring(2 * i, 2 * i + 2), 16);
        }

        JFJLibrary.INSTANCE.FDecoderKeyGenerationAlgorithm02(controlBlock_Input, PANBlock_Input, vendingKeyBlock_Input, Output);
        result = asciiToHex(Output, 8);
        return result;
    }

    public static String FEncryptionAlgorithm07(String tokenData, String decodeKey) {
        String result = "";
        byte[] Output = new byte[512];
        byte[] tokenData_Input = new byte[512];

        for(int i = 0; i < tokenData.length() / 2; ++i) {
            tokenData_Input[i] = (byte)Integer.parseInt(tokenData.substring(2 * i, 2 * i + 2), 16);
        }

        byte[] decodeKey_Input = new byte[512];

        for(int i = 0; i < decodeKey.length() / 2; ++i) {
            decodeKey_Input[i] = (byte)Integer.parseInt(decodeKey.substring(2 * i, 2 * i + 2), 16);
        }

        JFJLibrary.INSTANCE.FEncryptionAlgorithm07(tokenData_Input, decodeKey_Input, Output);
        result = asciiToHex(Output, 8);
        return result;
    }

    public static String FDecryptionAlgorithm07(String tokenData, String decodeKey) {
        String result = "";
        byte[] Output = new byte[512];
        byte[] tokenData_Input = new byte[512];

        for(int i = 0; i < tokenData.length() / 2; ++i) {
            tokenData_Input[i] = (byte)Integer.parseInt(tokenData.substring(2 * i, 2 * i + 2), 16);
        }

        byte[] decodeKey_Input = new byte[512];

        for(int i = 0; i < decodeKey.length() / 2; ++i) {
            decodeKey_Input[i] = (byte)Integer.parseInt(decodeKey.substring(2 * i, 2 * i + 2), 16);
        }

        JFJLibrary.INSTANCE.FDecryptionAlgorithm07(tokenData_Input, decodeKey_Input, Output);
        result = asciiToHex(Output, 8);
        return result;
    }

    public static String asciiToHex(byte[] asc, int len) {
        String chr = "";
        String hex = "";

        for(int i = 0; i < len; ++i) {
            hex = "00" + Integer.toHexString(asc[i]);
            int datalen = hex.length();
            chr = chr + hex.substring(datalen - 2).toUpperCase();
        }

        return chr;
    }

    public static String asciiToString(byte[] asc) {
        String chr = "";

        for(int i = 0; i < asc.length && asc[i] != 0; ++i) {
            chr = chr + (char)asc[i];
        }

        return chr;
    }

    public static byte[] stringToAscii(String chr) {
        byte[] asc = new byte[4096];
        char[] chars = chr.toCharArray();

        for(int i = 0; i < chr.length(); ++i) {
            asc[i] = (byte)chars[i];
        }

        return asc;
    }

    public static String substring(String str, int index, int length) {
        String s = "";
        if (str != null || str != "") {
            int strLen = str.length();
            if (length > 0 && index + length <= strLen) {
                s = str.substring(index, index + length);
            }
        }

        return s;
    }

    private static boolean CopyFileToJavaLibrary(String resourceFile, String suffix, String fileName) {
        String libraryPath = System.getProperty("java.library.path");
        String[] libraryPaths = libraryPath.split(suffix.equals(".so") ? ":" : ";");
        String[] var8 = libraryPaths;
        int var7 = libraryPaths.length;

        for(int var6 = 0; var6 < var7; ++var6) {
            String path = var8[var6];
            File destFile = new File(path);
            File fle = new File(path + "\\" + fileName);
            if (fle.exists()) {
                return true;
            }

            if (destFile.canWrite()) {
                CopyFile(resourceFile, new File(path, fileName));
                return true;
            }
        }

        return false;
    }

    private static void CopyFile(String resourceFile, File f) {
        FileOutputStream output = null;

        try {
            ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
            InputStream input = classLoader.getResourceAsStream(resourceFile);
            output = new FileOutputStream(f);
            byte[] buffer = new byte[1024];
            boolean var6 = false;

            int n;
            while(-1 != (n = input.read(buffer))) {
                output.write(buffer, 0, n);
            }

            output.flush();
        } catch (FileNotFoundException var17) {
            Logger.getLogger(TokenUtils.class.getName()).log(Level.SEVERE, (String)null, var17);
        } catch (IOException var18) {
            Logger.getLogger(TokenUtils.class.getName()).log(Level.SEVERE, (String)null, var18);
        } finally {
            try {
                if (output != null) {
                    output.close();
                }
            } catch (IOException var16) {
                Logger.getLogger(TokenUtils.class.getName()).log(Level.SEVERE, (String)null, var16);
            }

        }

    }
}
